package com.bingo.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bingo.common.R;
import com.bingo.dao.ClearLossMapper;
import com.bingo.entity.ClearLoss;
import com.bingo.entity.HisPool;
import com.bingo.entity.CurPool;
import com.bingo.entity.Site;
import com.bingo.entity.dto.CleanLoss;
import com.bingo.entity.dto.everyDayForm.EveryDayClear;
import com.bingo.entity.dto.intermediary.SiteClearLoss;
import com.bingo.entity.dto.resp.ClearRecord;
import com.bingo.entity.dto.resp.ReportBasic;
import com.bingo.entity.dto.resp.RespSiteClearLoss;
import com.bingo.entity.dto.todayForm.TodayClear;
import com.bingo.service.*;
import com.bingo.until.HostHolder;
import com.bingo.until.IsToday;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@Service
public class ClearLossServiceImpl extends ServiceImpl<ClearLossMapper, ClearLoss> implements ClearLossService {

    private HisPoolService hisPoolService;
    @Autowired
    public void setHisPoolService(HisPoolService hisPoolService) {
        this.hisPoolService = hisPoolService;
    }

    private CurPoolService curPoolService;
    @Autowired
    public void setCurPoolService(CurPoolService curPoolService) {
        this.curPoolService = curPoolService;
    }

    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    private SiteService siteService;
    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    private HostHolder hostHolder;
    @Autowired
    public void setHostHolder(HostHolder hostHolder) {
        this.hostHolder = hostHolder;
    }

    @Override
    public R add(String poolNo, Date date, String userId) {

        userId = hostHolder.getUser().getUserId();

        //查询该塘
        CurPool pool = curPoolService.getCurPoolByNo(poolNo);
        if (pool == null) {
            return R.error("不存在该塘!");
        }
        if (pool.getType() == 0) {
            return R.error("该塘已经是空塘状态!");
        }
        //保存记录
        ClearLoss clearLoss = new ClearLoss();
        clearLoss.setDate(date);
        clearLoss.setReportDate(new Date(System.currentTimeMillis()));
        clearLoss.setUserId(userId);
        clearLoss.setType(pool.getType());
        clearLoss.setPoolNo(poolNo);
        //查询该塘当天状态
        if (IsToday.isToday(date)) {
            clearLoss.setQuantity(pool.getQuantity());
            clearLoss.setWeight(pool.getWeight());
        } else {
            HisPool p = hisPoolService.getPoolByNoAndDate(poolNo, date);
            if (p == null) {
                return R.error("当天还不存在该塘");
            }
            clearLoss.setQuantity(p.getQuantity());
            clearLoss.setWeight(p.getWeight());
        }
        this.save(clearLoss);
        //将塘清空
        pool.setQuantity(0);
        pool.setWeight(0.0);
        //0为空塘状态
        pool.setType(0);
        curPoolService.updateById(pool);

        //如果不是当天
        if (!IsToday.isToday(date)) {
            QueryWrapper<HisPool> wrapper = new QueryWrapper<>();
            wrapper.eq("pool_no", poolNo);
            wrapper.between("date", date, new Date(System.currentTimeMillis()));
            List<HisPool> list = hisPoolService.list(wrapper);
            for (HisPool p : list) {
                p.setQuantity(0);
                p.setWeight(0.0);
                p.setType(0);
                hisPoolService.updateById(p);
            }
        }

        R<String> r = R.success("清塘成功");
        r.setStatusText("清塘损耗上报成功");
        return r;
    }

    @Override
    public CleanLoss selectCleanLoss(String poolNo, Date startTime, Date endTime) {
        CleanLoss cleanLoss = new CleanLoss();
        cleanLoss.setAmount(0);
        cleanLoss.setWeight(0.0);
        QueryWrapper<ClearLoss> wrapper = new QueryWrapper<>();
        wrapper.eq("pool_no", poolNo);
        wrapper.between("date", startTime, endTime);
        List<ClearLoss> list = this.list(wrapper);
        for (ClearLoss clearLoss : list) {
            cleanLoss.setAmount(cleanLoss.getAmount() + clearLoss.getQuantity());
            cleanLoss.setWeight(cleanLoss.getWeight() + clearLoss.getWeight());
        }
        return cleanLoss;
    }

    @Override
    public List<EveryDayClear> selectEveryDayClearLoss(List<String> poolNos, Date startDate, Date endDate) {

        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        List<EveryDayClear> list = new LinkedList<>();
        for (String poolNo : poolNos) {
            CurPool pool = curPoolService.getCurPoolByNo(poolNo);
            //初始化数据
            EveryDayClear everyDayClear = new EveryDayClear();
            everyDayClear.setPoolNo(poolNo);
            everyDayClear.setArea(pool.getArea());
            everyDayClear.setKey(poolNo);
            //LinkedList<TodayClear> todayClears = new LinkedList<>();
            HashMap<String, TodayClear> hashMap = new HashMap<>();
            //everyDayClear.setDataList(todayClears);
            everyDayClear.setDataMap(hashMap);
            everyDayClear.setTotalQuantity(0);
            everyDayClear.setTotalWeight(0.0);
            //查询该塘的清塘记录
            QueryWrapper<ClearLoss> wrapper = new QueryWrapper<>();
            wrapper.eq("pool_no", poolNo);
            wrapper.between("date", startDate, endDate);
            List<ClearLoss> clearLosses = this.list(wrapper);
            for (ClearLoss clearLoss : clearLosses) {
                TodayClear todayClear = new TodayClear();
                todayClear.setDate(clearLoss.getDate());
                todayClear.setPoolNo(poolNo);
                todayClear.setQuantity(clearLoss.getQuantity());
                todayClear.setWeight(clearLoss.getWeight());
                if (hashMap.containsKey(clearLoss.getDate().toString())) {
                    TodayClear todayClear1 = hashMap.get(clearLoss.getDate().toString());
                    todayClear1.setQuantity(todayClear1.getQuantity() + clearLoss.getQuantity());
                    todayClear1.setWeight(todayClear1.getWeight() + clearLoss.getWeight());
                    hashMap.put(clearLoss.getDate().toString(), todayClear1);
                } else {
                    hashMap.put(clearLoss.getDate().toString(), todayClear);
                }
                //todayClears.add(todayClear);
                everyDayClear.setTotalQuantity(everyDayClear.getTotalQuantity() + clearLoss.getQuantity());
                everyDayClear.setTotalWeight(everyDayClear.getTotalWeight() + clearLoss.getWeight());
            }
            list.add(everyDayClear);
        }
        return list;
    }

    @Override
    public List<ClearRecord> selectClearRecord(List<String> poolNos, Date startDate, Date endDate,String userId) {
        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        QueryWrapper<ClearLoss> wrapper = new QueryWrapper<>();
        wrapper.in("pool_no", poolNos);
        wrapper.between("date", startDate, endDate);
        if (userId != null && !userId.equals("")) {
            wrapper.eq("user_id", userId);
        }
        List<ClearLoss> list = this.list(wrapper);
        LinkedList<ClearRecord> clearRecords = new LinkedList<>();
        HashMap<String, String> allUser = userService.getAllUser();

        for (ClearLoss clearLoss : list) {
            ClearRecord clearRecord = new ClearRecord();
            ReportBasic reportBasic = new ReportBasic();
            reportBasic.setPoolNo(clearLoss.getPoolNo());
            String s = allUser.get(clearLoss.getUserId());
            reportBasic.setReporter(s);
            reportBasic.setDate(clearLoss.getDate());
            reportBasic.setReportDate(clearLoss.getReportDate());
            clearRecord.setReportBasic(reportBasic);
            clearRecord.setQuantity(clearLoss.getQuantity());
            clearRecord.setWeight(clearLoss.getWeight());
            clearRecord.setType(clearLoss.getType());
            clearRecords.add(clearRecord);
        }

        return clearRecords;
    }

    @Override
    public List<RespSiteClearLoss> selectSiteClearLoss(List<String> siteNos, Date startDate, Date endDate) {
        LinkedList<RespSiteClearLoss> list = new LinkedList<>();
        //如果没有传入塘号，则查询所有塘
        if (siteNos == null || siteNos.size() == 0) {
            siteNos = siteService.getAllSiteNo();
        }
        for (String siteNo : siteNos) {

            //初始化
            RespSiteClearLoss respSiteClearLoss = this.initRespSiteClearLoss(siteNo, 1);
            RespSiteClearLoss respSiteClearLossOld = this.initRespSiteClearLoss(siteNo, 2);
            this.initDataMap(respSiteClearLoss,startDate,endDate);
            this.initDataMap(respSiteClearLossOld,startDate,endDate);

            list.add(respSiteClearLoss);
            list.add(respSiteClearLossOld);

            //查询该场的所有塘
            List<String> poolNos = curPoolService.getPoolsBySiteNo(siteNo);
            if (poolNos == null || poolNos.size() == 0) {
                continue;
            }
            QueryWrapper<ClearLoss> wrapper = new QueryWrapper<>();
            wrapper.in("pool_no", poolNos);
            wrapper.between("date", startDate, endDate);
            List<ClearLoss> clearLosses = this.list(wrapper);

            //遍历清塘记录
            /*for (ClearLoss clearLoss : clearLosses) {
                //如果存在当天新鳗
                if (hashMap.containsKey(clearLoss.getDate().toString() + "-new")) {
                    SiteClearLoss siteClearLoss = hashMap.get(clearLoss.getDate().toString() + "-new");
                    siteClearLoss.setQuantity(siteClearLoss.getQuantity() + clearLoss.getQuantity());
                    siteClearLoss.setWeight(siteClearLoss.getWeight() + clearLoss.getWeight());
                    respSiteClearLoss.setTotalNewAccount(respSiteClearLoss.getTotalNewAccount() + clearLoss.getQuantity());
                    respSiteClearLoss.setTotalNewWeight(respSiteClearLoss.getTotalNewWeight() + clearLoss.getWeight());
                    hashMap.put(clearLoss.getDate().toString() + "-new", siteClearLoss);
                } else if (hashMap.containsKey(clearLoss.getDate().toString() + "-old")) {
                    SiteClearLoss siteClearLoss = hashMap.get(clearLoss.getDate().toString() + "-old");
                    siteClearLoss.setQuantity(siteClearLoss.getQuantity() + clearLoss.getQuantity());
                    siteClearLoss.setWeight(siteClearLoss.getWeight() + clearLoss.getWeight());
                    respSiteClearLoss.setTotalOldAccount(respSiteClearLoss.getTotalOldAccount() + clearLoss.getQuantity());
                    respSiteClearLoss.setTotalOldWeight(respSiteClearLoss.getTotalOldWeight() + clearLoss.getWeight());
                    hashMap.put(clearLoss.getDate().toString() + "-old", siteClearLoss);
                } else {
                    SiteClearLoss siteClearLoss = new SiteClearLoss();
                    siteClearLoss.setQuantity(clearLoss.getQuantity());
                    siteClearLoss.setWeight(clearLoss.getWeight());
                    siteClearLoss.setDate(clearLoss.getDate());
                    //如果是新鳗
                    if (clearLoss.getType() == 1) {
                        siteClearLoss.setType(1);
                        hashMap.put(clearLoss.getDate().toString() + "-new", siteClearLoss);
                        respSiteClearLoss.setTotalNewAccount(respSiteClearLoss.getTotalNewAccount() + clearLoss.getQuantity());
                        respSiteClearLoss.setTotalNewWeight(respSiteClearLoss.getTotalNewWeight() + clearLoss.getWeight());
                    } else if (clearLoss.getType() == 2) {
                        siteClearLoss.setType(2);
                        hashMap.put(clearLoss.getDate().toString() + "-old", siteClearLoss);
                        respSiteClearLoss.setTotalOldAccount(respSiteClearLoss.getTotalOldAccount() + clearLoss.getQuantity());
                        respSiteClearLoss.setTotalOldWeight(respSiteClearLoss.getTotalOldWeight() + clearLoss.getWeight());
                    }
                }
            }*/

            for (ClearLoss clearLoss : clearLosses) {
                if (clearLoss.getType()==1){
                    HashMap<String, SiteClearLoss> dataMap = respSiteClearLoss.getDataMap();
                    SiteClearLoss siteClearLoss = dataMap.get(clearLoss.getDate().toString());
                    siteClearLoss.setQuantity(siteClearLoss.getQuantity() + clearLoss.getQuantity());
                    siteClearLoss.setWeight(siteClearLoss.getWeight() + clearLoss.getWeight());
                    respSiteClearLoss.setTotalQuantity(respSiteClearLoss.getTotalQuantity() + clearLoss.getQuantity());
                    respSiteClearLoss.setTotalWeight(respSiteClearLoss.getTotalWeight() + clearLoss.getWeight());
                    dataMap.put(clearLoss.getDate().toString(), siteClearLoss);
                }else if (clearLoss.getType()==2){
                    HashMap<String, SiteClearLoss> dataMap = respSiteClearLossOld.getDataMap();
                    SiteClearLoss siteClearLoss = dataMap.get(clearLoss.getDate().toString());
                    siteClearLoss.setQuantity(siteClearLoss.getQuantity() + clearLoss.getQuantity());
                    siteClearLoss.setWeight(siteClearLoss.getWeight() + clearLoss.getWeight());
                    respSiteClearLossOld.setTotalQuantity(respSiteClearLossOld.getTotalQuantity() + clearLoss.getQuantity());
                    respSiteClearLossOld.setTotalWeight(respSiteClearLossOld.getTotalWeight() + clearLoss.getWeight());
                    dataMap.put(clearLoss.getDate().toString(), siteClearLoss);
                }
            }
        }

        return list;
    }




    private RespSiteClearLoss initRespSiteClearLoss(String siteNo, Integer type) {
        RespSiteClearLoss respSiteClearLoss = new RespSiteClearLoss();
        respSiteClearLoss.setSiteNo(siteNo);
        Site site = siteService.getSiteByNo(siteNo);
        respSiteClearLoss.setArea(site.getArea());
        if (type == 1) {
            respSiteClearLoss.setType(1);
            respSiteClearLoss.setKey(siteNo + "-new");
        }else {
            respSiteClearLoss.setType(2);
            respSiteClearLoss.setKey(siteNo + "-old");
        }
        HashMap<String, SiteClearLoss> hashMap = new HashMap<>();
        respSiteClearLoss.setDataMap(hashMap);
        respSiteClearLoss.setTotalQuantity(0);
        respSiteClearLoss.setTotalWeight(0.0);
        return respSiteClearLoss;
    }

    private void initDataMap(RespSiteClearLoss respSiteClearLoss,Date startTime, Date endTime){
        HashMap<String, SiteClearLoss> dataMap = respSiteClearLoss.getDataMap();
        Date tmpDate = new Date(startTime.getTime());
        //初始化dataMap
        while (tmpDate.getTime() <= endTime.getTime()) {
            SiteClearLoss siteClearLoss = new SiteClearLoss();
            siteClearLoss.setDate(new Date(tmpDate.getTime()));
            siteClearLoss.setQuantity(0);
            siteClearLoss.setWeight(0.0);
            dataMap.put(tmpDate.toString(), siteClearLoss);
            tmpDate.setTime(tmpDate.getTime() + 24 * 60 * 60 * 1000);
        }
    }


}
